package P043_AvoidShallowCopy;

import org.junit.Test;

/**
 * 让工具类不可实例化
 *
 * @author xufy1
 */
public class AvoidShallowCopy {

    /**
     * 拷贝比用new 生成对象性能提示明显
     * 浅拷贝存在对象拷贝不彻底
     */
    @Test
    public void test1() {
        Person f = new Person("父亲");
        Person s1 = new Person("大儿子", f);
        Person s2 = s1.clone();
        s2.setName("小儿子");
        System.out.println(s1.getName() + " 的父亲是 " + s1.getFather().getName());
        System.out.println(s2.getName() + " 的父亲是 " + s2.getFather().getName());
    }

    @Test
    public void test2() {
        Person f = new Person("父亲");
        Person s1 = new Person("大儿子", f);
        Person s2 = s1.clone();
        s2.setName("小儿子");

        s1.getFather().setName("父亲父亲");

        System.out.println(s1.getName() + " 的父亲是 " + s1.getFather().getName());
        System.out.println(s2.getName() + " 的父亲是 " + s2.getFather().getName());
    }
}

class Person implements Cloneable {
    private String name;
    private Person father;

    public Person(String _name) {
        name = _name;
    }

    public Person(String _name, Person _parent) {
        name = _name;
        father = _parent;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Person getFather() {
        return father;
    }

    public void setFather(Person father) {
        this.father = father;
    }


    @Override
    public Person clone() {
        Person p = null;
        try {
            /**
             * 拷贝规则：
             * 1.只是拷贝基本类型 int boolean
             * 2.实例对象 是 拷贝对象地址引用
             * 3.String字符串(直接理解为基本类型)， 从字符串池生成新的字符串，原有字符串对象不变
             */
            p = (Person) super.clone();
            //重新new 一个新的，保证和原来的不是一个
            p.setFather(new Person(p.getFather().getName()));
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return p;
    }
}
